package com.dong.auth.security.filter;

import com.dong.auth.security.authentication.Authentication;
import com.dong.auth.security.authentication.holder.DongAuthenticationHolder;
import com.dong.auth.security.authorization.AbstractAuthorizationInterceptor;
import com.dong.auth.security.exception.AuthenticationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;

/**
 * 检验请求是否已经被授权的filter
 *
 * @author zhaodongchao
 * @version V1.0
 * @date 2021/10/13 20:20
 */
public class AuthorizationInterceptorFilter extends AbstractAuthorizationInterceptor implements Filter {
    private static final String FILTER_APPLIED = "__dong_security_filter_interceptor_filter_applied";

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        logger.info("开始执行鉴权过滤器啦！");
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;

        //1 判断是否重复请求
        if (httpServletRequest.getAttribute(FILTER_APPLIED) != null) {
            //如果已经执行过，就直接往下执行
            chain.doFilter(request, response);
            return;
        }
        httpServletRequest.setAttribute(FILTER_APPLIED, Boolean.TRUE);

        //2 从认证信息容器中获取当前登录用户的认证信息
        Authentication authentication = DongAuthenticationHolder.get();
        if (null == authentication || !authentication.isAuthenticated()) {
            //表示没有登录,抛出拒绝访问异常
            throw new AuthenticationException("请登录后再进行操作");
        }
        //3 如果已经登录，就获取配置的资源的权限，来进行授权判定逻辑
        Collection<String> configAuthorities = getConfigAuthorities();
        if (null == configAuthorities || configAuthorities.isEmpty()) {
            //如果没有配置资源特殊权限，就继续执行
            chain.doFilter(request, response);
            return;
        }

        //4 判定是否有该权限，如果有就继续往下执行，没有权限，就抛出拒绝访问异常
        this.decide(authentication, configAuthorities);
        //往下执行
        chain.doFilter(request, response);

    }



    private Collection<String> getConfigAuthorities() {
        //TODO 获取配置
        return new ArrayList<>();
    }
}
